#pragma once
#include "http_data.h"
#include "websocket.h"
#include <functional>
#include <string>
#include <unordered_map>

namespace co_async {
class HttpServer {
public:
  friend class WebSocket;
  using WsHandler = std::function<Task<std::string>(const std::string &)>;
  using Handler = std::function<Task<HttpResponse>(const HttpRequest &)>;
  using HandlerMap = std::unordered_map<std::string, Handler>;
  HttpServer(std::string_view addr, uint16_t port);

  // void route(std::string path, Handler task) { m_routes[path] = task; }
  void post(const std::string &path, Handler task);
  void get(const std::string &path, Handler task);
  void set_static_dir(std::string_view dir);
  WebSocket& update(const std::string &path);

  void serve();

private:
  std::string m_addr;
  uint16_t m_port;

  std::array<HandlerMap, Method::UNKNOWN - 1> m_handlers;
  // WebSocket m_ws;
  std::unordered_map<std::string, WebSocket::Ptr> m_ws_map;
  Task<void, HttpPromise> handle_connection();
  Task<> run();
};
} // namespace co_async
